/*
 * @Author       : 邱狮杰
 * @Date         : 2021-07-29 11:41:25
 * @LastEditTime: 2021-08-16 14:15:33
 * @FilePath     : /preselectedyarn/src/service/index.ts
 * @Description  :
 */

import API_CONFIG from './api'
import axios from './axios'
import { StoreConfigNameCollect, AXIOS_DEFAULT_CONFIG } from '../config/index'
import { ApiUnitConfig } from '../types/axios'
interface ConfigFace {
  [propName: string]: ApiUnitConfig[]
}

interface GetBaseConfig {
  sep: string
  config: ConfigFace
  debug: boolean
}

interface GetStrBuild {
  namespace: string
  sep: string
  debug: boolean
  unitConfig: ApiUnitConfig[]
}

function isObject(object: unknown) {
  return Object.prototype.toString.call(object) === '[object Object]'
}
// 处理auth
async function handleAuth(option: any) {
  const {
    headers,
    // isUpload,
    // baseURL, url,
    // data, params
  } = option
  let newHeaders = {}
  newHeaders = {
    ...headers,
    Authorization: StoreConfigNameCollect.auth_type + ' ' + localStorage.getItem(StoreConfigNameCollect.token),
  }
  // @ts-ignore
  return axios({ ...option, headers: newHeaders })
}
function handMethod(option: ApiUnitConfig) {
  const { method, isFormData } = option
  if (method.toLowerCase() === 'post' || method.toLowerCase() === 'put' || method.toLowerCase() === 'patch') {
    if (isFormData) {
      option.data = new FormData({ ...option.params })
    } else {
      option.data = option.params
    }
    delete option.params
  }
}

// 合并data
function collectData(userParams: any, defaultParams: any) {
  if (!userParams || !isObject(userParams)) {
    userParams = {}
  }
  if (!defaultParams || !isObject(defaultParams)) {
    defaultParams = {}
    return {}
  }
  Object.keys(defaultParams).forEach(key => {
    defaultParams[key] = userParams[key]
  })
  // return defaultParams
  return { ...defaultParams, ...userParams }
}
class MakeApi {
  api: any
  constructor(options: GetBaseConfig) {
    this.api = {}
    this.apiBuilder(options)
  }

  apiBuilder({ sep = '|', config = {}, debug = false }: GetBaseConfig) {
    Object.keys(config).forEach(namespace => {
      this._apiSingleBuilder({
        namespace,
        sep,
        debug,
        unitConfig: config[namespace],
      })
    })
  }

  _apiSingleBuilder({ namespace, sep = '|', unitConfig = [], debug = false }: GetStrBuild) {
    unitConfig.forEach(api => {
      const { name, desc, params, method, path, auth, isFormData, needToken, baseURL, isUpload } = api
      let url = ''
      url = baseURL + path
      debug && new Error(`${name}, ${url} :接口name属性不能为空`)
      Object.defineProperty(this.api, `${namespace}${sep}${name}`, {
        // outerOptions
        value(outerParams: any, outerOptions: any) {
          const _data = collectData(outerParams, params)
          const _options: any = {
            url: path,
            nameURL: `${namespace}${sep}${name}`,
            isUpload,
            desc,
            method,
            baseURL: baseURL,
            headers: {},
            params: _data,
            cloneParams: _data,
            auth,
            isFormData,
            cancelToken: null,
            onDownloadProgress: null,
            onUploadProgress: null,
            needToken,
          }
          if (outerOptions && isObject(outerOptions)) {
            _options.cancelToken = outerOptions.cancel
            _options.onDownloadProgress = outerOptions.onDownloadProgress
            _options.onUploadProgress = outerOptions.onUploadProgress
          }
          // 这一步处理post请求
          handMethod(_options)
          return handleAuth(_options)
        },
      })
    })
  }
}
// @ts-ignore
export default new MakeApi({
  config: API_CONFIG,
  ...AXIOS_DEFAULT_CONFIG,
}).api
